Skip to content

First iteration on option attributes - #1231

Draft
jaapio wants to merge 6 commits into
mainfrom
task/directive-options
Draft

First iteration on option attributes#1231
jaapio wants to merge 6 commits into
mainfrom
task/directive-options

Conversation

@jaapio

@jaapio jaapio commented Jun 17, 2025

Copy link
Copy Markdown
Member

Directive attributes & compile-time directive processing

Introduces a new attribute-based declaration system for reStructuredText directives and moves directive processing from the parse phase into the compile phase.

Moving directive processing to a compiler pass is the groundwork that enables upcoming features such as option validation — with directives now declaratively describing their options via attributes, the framework can inspect and validate them centrally instead of each directive doing ad-hoc parsing.

Features

#[Directive] and #[Option] attributes

  • New phpDocumentor\Guides\RestructuredText\Directives\Attributes\Directive attribute declares a directive's name and aliases on the class, replacing the abstract getName() / getAliases() methods.
  • New repeatable #[Option] attribute (OptionType, default value, description, example) declares the options a directive supports — used for automatic option validation, type coercion, and documentation.

Compile-time directive processing

  • New DirectiveNode represents a parsed directive during compilation and is now processed by a dedicated DirectiveProcessPass compiler pass instead of being resolved eagerly by the parser.
  • New ReverseNodeTransformer interface, with support in DocumentNodeTraverser, so parent transforms run after their children.
  • Directives expose a createNode(DirectiveNode) entry point; a backward-compat process() path (with isUpgraded()) keeps existing directives working while they are migrated.

Upgraded directives

  • Migrated to the attribute model: admonitions (attention, caution, danger, error, hint, important, note, tip, warning), version-change directives (versionadded, versionchanged, deprecated), figure, image, include, confval, youtube, and others.
  • readOption() / readAllOptions() on BaseDirective now coerce values to the declared OptionType and apply attribute defaults (e.g. youtube width/height/allow/allowfullscreen).
  • Admonitions now correctly apply the option-provided CSS class to the rendered node.

Deprecations

  • Directives without a #[Directive] attribute now trigger a deprecation when their name is resolved, pointing to documentation on migrating custom directives.

Notes

  • Includes a base-line merge of update-security-issues and a dependency bump.
  • This is a first iteration; remaining built-in directives will be migrated to the attribute/compile-time model in follow-ups.

@jaapio
jaapio force-pushed the task/directive-options branch from 0c15922 to 1823455 Compare March 1, 2026 19:50
@jaapio
jaapio force-pushed the task/directive-options branch from e1c76b1 to fd93e7f Compare August 28, 2026 14:38
jaapio added 6 commits August 28, 2026 16:43
The new option attribute makes it easier to validate directives. An
extra advantage is that we can use the new attributes to document the
directive options.
The reverse node transformer allows us to transform children of nodes before
the node itself is transformed. This is needed for directives which may contain
child nodes that need processing.
@jaapio
jaapio force-pushed the task/directive-options branch from fd93e7f to f9686be Compare August 28, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant